package com.asm.mybatis.javassist;

import com.asm.mybatis.dao.CarDao;
import org.apache.ibatis.javassist.*;
import org.junit.Test;

import java.lang.reflect.Method;

public class CarMapperImplByJavassist {

    /**
     * 使用javassist生成dao接口的实现类
     */
    @Test
    public void generateCarMapperImpl() throws Exception {
        // 1、构造类池
        ClassPool pool = ClassPool.getDefault();

        CtClass ctClass = pool.makeClass("com.asm.mybatis.dao.CarDaoImpl");
        CtClass ctInterface = pool.makeInterface("com.asm.mybatis.dao.CarDao");

        ctClass.addInterface(ctInterface);
        // 如何获取接口中的方法

//        CtMethod[] declaredMethods = ctInterface.getDeclaredMethods();
        Method[] declaredMethods = CarDao.class.getDeclaredMethods();
        // 遍历添加方法
        for (Method declaredMethod : declaredMethods) {
            StringBuilder methodCode = new StringBuilder();
//            void deleteOneById(Long id);
            methodCode.append("public ");
            // public
            methodCode.append(declaredMethod.getReturnType().getName() + " ");
            // public void
            methodCode.append(declaredMethod.getName());
            // public void deleteOneById    下一步拼参数
            methodCode.append("(");
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                // 拼形参类型
                methodCode.append(parameterTypes[i].getName());
                methodCode.append(" ");
                // 拼形参名字
                methodCode.append("arg" + i);
                if (i != parameterTypes.length - 1) {
                    methodCode.append(",");
                }
            }
            methodCode.append("){");
            // 拼方法体
            // public void deleteOneById(){
            methodCode.append("System.out.println(\"" + declaredMethod + "\");");
            // 拼返回值
            String returnName = declaredMethod.getReturnType().getSimpleName();
            if ("void".equals(returnName)) {
                methodCode.append("}");
            } else {
                methodCode.append("return null;}");
            }
            try {
                ctClass.addMethod(CtMethod.make(methodCode.toString(), ctClass));
            } catch (CannotCompileException e) {
                throw new RuntimeException(e);
            }
            //System.out.println(methodCode);
        }
        // // 在内存中生成class，并且加载到JVM当中
        Class<?> clazz = ctClass.toClass();
        // new 对象
        CarDao carDao = (CarDao)clazz.newInstance();
        // 调用方法
        carDao.print();


    }
}
